﻿/*
 * Authors:    Kęstutis Džiautas
 *             Edmundas Matusevičius
 * University: VU, MIF, SE, 4 course
 * Date:       2010-12-18
 * Version:    1.0
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SemAnalyzer
{
    public class SemanticAnalyzer
    {
        private string lexem;
        private int lexemNumber;

        private void expr() {
            opAssign();
        }

        private void exprTail() {
            
        }

        private void opAssign() {
            opOr();
        }

        private void opAssignTail() {

        }

        private void opOr() {
            opAnd();
        }

        private void opOrTail() {

        }

        private void opAnd() {
            opEquate();
        }

        private void opAndTail() {

        }

        private void opEquate() {
            opCompare();
        }

        private void opEquateTail() {

        }

        private void opCompare() {
            opAdd();
        }

        private void opCompareTail() {

        }

        private string opAdd() {
            string opMultLexem;
            string opAddTailLexem;

            opMultLexem = opMult();
            opAddTailLexem = opAddTail();

            if (opAddTailLexem == null) {
                return opMultLexem;
            } else {
                // todo
                return null;
            }
        }

        private string opAddTail() {
            if (lexem.Equals("+")) {
                //scan();
                //addToTree();
                return null;
            } else if (lexem.Equals("-")) {
                // todo
                return null;
            }
            return null;
        }

        private string opMult() {
            string opUnaryLexem;
            string opMultTailLexem;

            opUnaryLexem = opUnary();
            opMultTailLexem = opMultTail(opUnaryLexem);

            if (opMultTailLexem == null) {
                return opUnaryLexem;
            } else {
                //todo
                return null;
            }
        }

        private string opMultTail(string opUnaryLexem) {
            if (lexem.Equals("*")) {
                //scan();
                // 1 * 2
                //addToTree(opUnaryLexem, "*", lexem);
                // todo
                return null;
            } else if (lexem.Equals("/")) {
                // todo
                return null;
            } else if (lexem.Equals("%")) {
                return null;
            }
            return null;
        }

        private string opUnary() {
            if (lexem.Equals("!")) {
                // todo
                return null;
            } else if (lexem.Equals("-")) {
                // todo
                return null;
            } else {
                string opStructLexem;

                opStructLexem = opStruct();

                return opStructLexem;
            }
        }

        private string opStruct() {
            string valueLexem;
            string opStructTailLexem;

            valueLexem = value();
            //scan();
            opStructTailLexem = opStructTail();

            if (opStructTailLexem == null) {
                return valueLexem;
            } else {
                // todo
                return null;
            }
        }

        private string opStructTail() {
            if (lexem.Equals(".")) {
                // todo
                return null;
            } else {
                return null;
            }
        }

        private string value() {
            if (lexem.Equals("(")) {
                // todo
                return null;
            } else if (lexem.Equals("{")) {
                // todo
                return null;
            } else {
                switch (lexemNumber) {
                    case 100:   // id
                        break;
                    case 200:   // char
                        break;
                    case 201:   // string
                        break;
                    case 202:   // integer
                        return lexem;
                    case 203:   // float
                        break;
                    default:
                        break;
                }
                // todo
                return null;
            }
        }

        private void valueHead() {
            
        }

        private void valueEnd() {

        }

        private void valueBracketsHead() {

        }

        private void valueBracketsEnd() {

        }



        static void Main(string[] args)
        {
            SemanticAnalyzer semAn = new SemanticAnalyzer();
            semAn.InicializeDomain();
            semAn.varTable = new VariableTable();
        }
        /// <summary>
        /// Inicialize global domain
        /// </summary>
        public void InicializeDomain()
        {
            Domains = new List<string>();
            Domains.Add("Global");
            currentDomain = Domains[0];
        }
        /// <summary>
        /// Method to create new domain
        /// </summary>
        public void EnterDomain()
        {
            Domains.Add("Domain" + Domains.Count);
            currentDomain = Domains[Domains.Count - 1];
        }
        /// <summary>
        /// Method to delete last domain
        /// </summary>
        public void LeaveDomain()
        {
            if (Domains.Count != 0)
            {
                varTable.CleanDomain(Domains[Domains.Count - 1]);
                Domains.RemoveAt(Domains.Count - 1);
                currentDomain = Domains[Domains.Count - 1];
            }
        }

        VariableTable varTable;
        /// <summary>
        /// Current domain
        /// </summary>
        public static string currentDomain
        {
            get;
            private set;
        }
        /// <summary>
        /// Domain list
        /// </summary>
        List<string> Domains;
    }
}
